/*
 * CUtility.java
 *
 * Copyright (c) 2009 Giles Millward (Manigra). All rights reserved.
 *
 * This file is part of JRogueDPS.
 *
 * JRogueDPS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JRogueDPS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with JRogueDPS.  If not, see <http://www.gnu.org/licenses/>.
 */
package utility;

import java.util.logging.Level;
import java.util.logging.Logger;
import jroguedps.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.MalformedURLException;
import javax.swing.ImageIcon;
import javax.imageio.ImageIO;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;

/**
 *
 * @author Mani
 */
public class CUtility {

    static public boolean fileExists(String p_fileName) {
        File f = new File(p_fileName);
        return f.exists();
    }

    static private void writeImage(String p_fileName, BufferedImage p_image) {
        File file = new File(p_fileName + ".jpg");
        try {
            file.createNewFile();
            ImageIO.write(p_image, "jpeg", file);
        } catch (IOException e) {
        }
    }

    static public void populateFilelistComboBox(String p_dataFolder, JComboBox p_comboBox) {
        File dir = new File("data/" + p_dataFolder + "/");

        p_comboBox.removeAllItems();
        // It is also possible to filter the list of returned files.
        // This example does not return any files that start with `.'.
        FilenameFilter l_filter = new FilenameFilter() {

            public boolean accept(File p_dir, String p_name) {
                return p_name.endsWith(".xml");
            }
        };

        String[] l_children = dir.list(l_filter);
        if (l_children == null) {
            // Either dir does not exist or is not a directory
        } else {
            for (int i = 0; i < l_children.length; i++) {
                // Get filename of file or directory minus the .xml extension
                String l_filename = l_children[i].substring(0, l_children[i].lastIndexOf("."));
                p_comboBox.addItem(l_filename);
            }
        }
    }

    static public ImageIcon getTalentIcon(String p_tree, String p_talentName, boolean p_getColorVersion) {
        String l_niceFileName = p_tree.toLowerCase() + "_" + p_talentName.replaceAll("\\s+", "").toLowerCase();
        if ((!fileExists(l_niceFileName + ".jpg") &&
                p_getColorVersion) || CGlobal.g_writeImagesToDisk) {
            // Get images from blizzard webpage
            Image l_image = getTalentImage(p_tree, p_talentName);
            MediaTracker l_tracker = new MediaTracker(CGlobal.g_jFrame);
            l_tracker.addImage(l_image, 0);
            try {
                l_tracker.waitForAll();
            } catch (InterruptedException e) {
            }

            // Write colored version to disk
            BufferedImage l_imageCopy = new BufferedImage(43, 45, BufferedImage.SCALE_SMOOTH);
            l_imageCopy.createGraphics().drawImage(l_image, 0, 0, CGlobal.g_jFrame);
            writeImage(l_niceFileName, l_imageCopy);

            // Write grayscale version to disk
            BufferedImage l_imageCopy2 = new BufferedImage(43, 45, BufferedImage.TYPE_BYTE_GRAY);
            l_imageCopy2.createGraphics().drawImage(l_image, 0, 0, CGlobal.g_jFrame);
            writeImage(l_niceFileName + "_gray", l_imageCopy2);
        }

        if (p_getColorVersion) {
            return new ImageIcon(l_niceFileName + ".jpg");
        }

        return new ImageIcon(l_niceFileName + "_gray.jpg");
    }

    static private Image getTalentImage(String p_tree, String p_talentName) {
        if (p_talentName.toLowerCase().equals("dirty tricks")) {
            // Dirty Deeds image is not called dirtydeeds.jpg :/
            p_talentName = "Improved Sap";
        }

        p_talentName = p_talentName.replaceAll("\\s+", "");
        String l_url = "http://www.worldofwarcraft.com/shared/global/talents//wrath/rogue/images/" + p_tree.toLowerCase() + "/" + p_talentName.toLowerCase() + ".jpg";
        Image image = getImageFromURL(l_url);
        if (image == null) {
            System.out.println("Image " + p_tree + "/" + p_talentName + " was not found");
        } else {
            System.out.println("Got image " + p_tree + "/" + p_talentName);
        }
        return image;
    }

    static public Image getImageFromURL(String p_url) {
        try {
            // Create a URL for the image's location
            URL url = new URL(p_url);
            System.out.println("Getting image " + p_url);
            // Get the image
            @SuppressWarnings("static-access")
            Image image = Toolkit.getDefaultToolkit().getDefaultToolkit().createImage(url);
            return image;
        } catch (MalformedURLException e) {
            return null;
        } catch (IOException e) {
        }
        return null;
    }

    static public void writeToClipboard(String p_string) {
        // Get the system clipboard
        Clipboard systemClipboard =
                Toolkit.getDefaultToolkit().getSystemClipboard();

        Transferable transferableText = new StringSelection(p_string);
        systemClipboard.setContents(transferableText, null);
    }

    static public BufferedImage getBufferedImageFromImageIcon(ImageIcon p_imageIcon) {
        Image l_image = p_imageIcon.getImage();

        // Create empty BufferedImage, sized to Image
        BufferedImage l_buffImage =
                new BufferedImage(
                l_image.getWidth(null),
                l_image.getHeight(null),
                BufferedImage.TYPE_INT_ARGB);

        // Draw Image into BufferedImage
        Graphics g = l_buffImage.getGraphics();
        g.drawImage(l_image, 0, 0, null);
        return l_buffImage;
    }

    /**
     * Convenience method that returns a scaled instance of the
     * provided {@code BufferedImage}.
     *
     * @param img the original image to be scaled
     * @param targetWidth the desired width of the scaled instance,
     *    in pixels
     * @param targetHeight the desired height of the scaled instance,
     *    in pixels
     * @param hint one of the rendering hints that corresponds to
     *    {@code RenderingHints.KEY_INTERPOLATION} (e.g.
     *    {@code RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR},
     *    {@code RenderingHints.VALUE_INTERPOLATION_BILINEAR},
     *    {@code RenderingHints.VALUE_INTERPOLATION_BICUBIC})
     * @param higherQuality if true, this method will use a multi-step
     *    scaling technique that provides higher quality than the usual
     *    one-step technique (only useful in downscaling cases, where
     *    {@code targetWidth} or {@code targetHeight} is
     *    smaller than the original dimensions, and generally only when
     *    the {@code BILINEAR} hint is specified)
     * @return a scaled version of the original {@code BufferedImage}
     */
    static public BufferedImage getScaledInstance(BufferedImage img,
            int targetWidth,
            int targetHeight,
            Object hint,
            boolean higherQuality) {
        int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage ret = (BufferedImage) img;
        int w, h;
        if (higherQuality) {
            // Use multi-step technique: start with original size, then
            // scale down in multiple passes with drawImage()
            // until the target size is reached
            w = img.getWidth();
            h = img.getHeight();
        } else {
            // Use one-step technique: scale directly from original
            // size to target size with a single drawImage() call
            w = targetWidth;
            h = targetHeight;
        }

        do {
            if (higherQuality && w > targetWidth) {
                w /= 2;
                if (w < targetWidth) {
                    w = targetWidth;
                }
            }

            if (higherQuality && h > targetHeight) {
                h /= 2;
                if (h < targetHeight) {
                    h = targetHeight;
                }
            }

            BufferedImage tmp = new BufferedImage(w, h, type);
            Graphics2D g2 = tmp.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            g2.drawImage(ret, 0, 0, w, h, null);
            g2.dispose();

            ret = tmp;
        } while (w != targetWidth || h != targetHeight);

        return ret;
    }

    static public String openXMLFileOpenDialog(String p_path, String p_title) {
        return openXMLFileDialog(p_path, p_title, false);
    }

    static public String openXMLFileSaveDialog(String p_path, String p_title) {
        return openXMLFileDialog(p_path, p_title, true);
    }

    static public String openXMLFileDialog(String p_path, String p_title, boolean p_save) {
        String l_path = CGlobal.g_pwd + "/data/" + p_path + "/";
        JFileChooser l_fc = new JFileChooser();
        javax.swing.filechooser.FileFilter l_fileFilter = new javax.swing.filechooser.FileFilter() {

            //Accept all directories and all .xml files.
            public boolean accept(File f) {
                if (f.isDirectory()) {
                    return true;
                }

                if (f.getName().endsWith(".xml")) {
                    return true;
                }

                return false;
            }

            //The description of this filter
            public String getDescription() {
                return "XML Data Files";
            }
        };

        l_fc.setName(p_title);
        l_fc.addChoosableFileFilter(l_fileFilter);
        l_fc.setFileFilter(l_fileFilter);
        l_fc.setCurrentDirectory(new File(l_path));
        int l_returnVal;

        if (p_save) {
            l_returnVal = l_fc.showSaveDialog(CGlobal.g_jFrame);
        } else {
            l_returnVal = l_fc.showOpenDialog(CGlobal.g_jFrame);
        }

        if (l_returnVal == JFileChooser.APPROVE_OPTION) {
            File l_file = l_fc.getSelectedFile();
            try {
                l_path = l_file.getCanonicalPath();
            } catch (IOException ex) {
                Logger.getLogger(CUtility.class.getName()).log(Level.SEVERE, null, ex);
                return null;
            }

            System.out.println("File string [" + l_path + "]");
            return l_path;
        }

        return null;
    }

    static public String boolToString(boolean p_value)
    {
        if (p_value)
        {
            return "true";
        }

        return "false";
    }

    static public boolean stringToBool(String p_value)
    {
        if (p_value.equals("true"))
        {
            return true;
        }

        return false;
    }
}
